package com.shyroke.daydayzhuansvc.service.impl;

import com.shyroke.daydayzhuanapi.dto.ProjectDto;
import com.shyroke.daydayzhuansvc.service.IOSSService;
import com.shyroke.daydayzhuansvc.util.CommonUtil;
import com.shyroke.daydayzhuansvc.util.ImageUtils;
import com.shyroke.daydayzhuansvc.util.OSSClientConstants;
import com.shyroke.daydayzhuansvc.util.OSSClientUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 类名 ：
 * 用法 ：
 * 创建人 ： shyroke
 * 时间：2019/1/14 16:51
 */
@Service
public class OSSService implements IOSSService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private OSSClientUtils ossClientUtils;
    @Value("${spider_img_suff}")
    private String spider_img_suff;

    @Override
    public void uploadImg(MultipartFile file,String path) throws Exception {
     ossClientUtils.uploadImg(file.getInputStream(),path);
    }

    @Override
    public void uploadImg(String source, String target,String reffer) throws Exception {
        long start = System.currentTimeMillis();
        URL url = new URL(source);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setConnectTimeout(5 * 1000);
        conn.setRequestProperty("User-agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36");
        if(reffer != null){
            conn.setRequestProperty("referer", reffer);
        }
        InputStream inputStream = conn.getInputStream();// 通过输入流获取图片数据
        logger.info("加载图片:{},耗时：{}",source,(System.currentTimeMillis() - start));
        long start1 = System.currentTimeMillis();
        ossClientUtils.uploadImg(inputStream,target);
        logger.info("上传图片耗时：{}",(System.currentTimeMillis() - start1));
    }

    @Override
    public String getImgUrl(String path) {
        return ossClientUtils.getImgUrl(path);
    }


    @Override
    public URL getImgURL(String path) {
        return ossClientUtils.getImgURL(path);
    }

    @Override
    public void deleteImg(String bucketName, String path) {
        ossClientUtils.deleteImg(bucketName,path);
    }

    @Override
    public void uploadFile(MultipartFile file, String sitemapPath) throws  Exception{
        ossClientUtils.uploadImg(file.getInputStream(),sitemapPath);
    }

    @Override
    public InputStream getFileObj(String bucketName,String sitemapPath) throws Exception {
        return ossClientUtils.getFileObj(bucketName,sitemapPath);
    }

    @Override
    public void handleImg(ProjectDto project, String reffer) throws Exception {
        //存放该文章所有图片，等图片保存到oss后，会替换成oss上图片的路径
       List<String> urlList = new ArrayList<>();
        try {
            String title = project.getTitle();
            Document document = Jsoup.parse(project.getContent());
            Elements elements = document.select("img");
            if(elements != null && elements.size()>0){
                for(int i= 0;i<elements.size();i++){
                    Element imgEle = elements.get(i);
                    String src = imgEle.attr("src");
                    if(!src.contains(".jpg") && !src.contains(".png") && !src.contains(".jpeg")){
                        continue;
                    }
                    if(!StringUtils.isEmpty(src) && src.indexOf(OSSClientConstants.BUCKET_NAME+"."+OSSClientConstants.ENDPOINT) != -1){
                        continue;
                    }
                    String file = imgEle.attr("file");
                    String origin = imgEle.attr("data-original");
                    String srcset = imgEle.attr("srcset");
                    //图片居中
                    imgEle = imgEle.wrap("<div style='text-align:center'></div>");
                    //如果是相对路径则补全为完整路径
                    if(!StringUtils.isEmpty(origin)){
                        if(!origin.startsWith("http")){
                            origin = project.getSourceURL()+origin;
                        }
                        imgEle.attr("src",origin);
                        urlList.add(origin);
                    }else if(!StringUtils.isEmpty(srcset)){
                        if(!srcset.startsWith("http")){
                            srcset = project.getSourceURL()+srcset;
                        }
                        imgEle.attr("src",srcset);
                        urlList.add(srcset);
                    }else if(!StringUtils.isEmpty(src)){
                        if(!src.startsWith("http")){
                            src = project.getSourceURL()+src;
                        }
                        imgEle.attr("src",src);
                        urlList.add(src);
                    }else if(!StringUtils.isEmpty(file)){
                        if(!file.startsWith("http")){
                            file = project.getSourceURL()+file;
                        }
                        imgEle.attr("src",file);
                        urlList.add(file);
                    }
                    //设置图片的alt
                    Element element = elements.get(i);
                    element.attr("alt",Jsoup.parse(title).text()+"  第"+(i+1)+"张");
                    element.attr("style","max-width: 80%;");
                }
                project.setContent(document.html());
            }
        }catch (Exception e){
            logger.info(e.getMessage());
            throw new RuntimeException("图片解析错误!");
        }

        //遍历所有图片，并上传，上传成功后替换value
        logger.info("需要上传的图片列表：{}",urlList);
        for(String url:urlList){
            if(ImageUtils.filterUrl(url)){ //检测图片链接是否需要过滤
                continue;
            }
            //处理特殊格式的url，比如https://www.gushengwl.com/../../../upFiles/infoImg/20210924/202109240953323961.jpg
            boolean isSpencil = url.indexOf("../")!=-1;
            String urlOld = null;
            if(isSpencil){
                urlOld = url;
            }
            url = url.replaceAll("\\.\\.\\/","");

            String img_name = CommonUtil.getUUID(); //上传图片的图片名
            String path = OSSClientConstants.CONTENT_PATH+CommonUtil.getDateByFormat(new Date(),"yyyy-MM-dd")+"/"+img_name+spider_img_suff;

            for(int i=0;i<5;i++) {
                // 直到服务器反应过来 再接着访问 处于过载状态 代码接着休息
                try {
                    this.uploadImg(url,path,reffer);
                    //运行成功则接着访问
                    break;
                } catch (Exception e) {
                    System.out.println("服务器过载，休息10秒！");
                    Thread.sleep(10000);
                    //结束本次循环
                    continue;
                }
            }
            String newImgUrl = this.getImgUrl(path);

            if(isSpencil){
                //说明该图片地址有参数，那么就必须在&后加amp；否则reaplac无效
                url = this.handleUrl(urlOld);
            }else{
                //说明该图片地址有参数，那么就必须在&后加amp；否则reaplac无效
                url = this.handleUrl(url);
            }

            logger.info("上传后的图片地址:{}",url);

            String newContent = project.getContent().replace(url,newImgUrl);
            project.setContent(newContent);
        }
    }

    private String handleUrl(String url) {

        if(url.indexOf("?")!=-1){//说明该图片地址有参数，那么就必须在&后加amp；否则reaplac无效
            String[] urlArr = url.split("\\?");
            String url_pre = urlArr[0]; //路径
            String url_suff = urlArr[1]; //参数
            String[] paramArr = url_suff.split("\\&");//参数数组
            String newUrl = url_pre + "?";
            if(paramArr == null || paramArr.length == 0){
                return url;
            }
            for(int i=0;i<paramArr.length;i++){
                newUrl += paramArr[i] + "&amp;";
            }
            newUrl = newUrl.substring(0,newUrl.length()-5);
            return  newUrl;

        }else{
            return url;
        }
    }
}
